﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

using NeedsMoreNinja.EventManager;

namespace Darwin.Source.Particle_Systems
{
    public class CParticleManager : IEventListener<SunXNA.SStep>
    {
         const int MAX_EXPLOSION = 10;
         const int MAX_EXPLOSION_PARTICLES = 10;
         const int MAX_RAIN_PARTICLES = 1000;
         float m_iMinTerrainHeight;

        // Particle system locations in List
        int m_iRainPosition;
        int m_iExplosionStart;
        int m_iExplosionEnd;
        private Game r_gGame;

        private List< CBaseParticleSystem > m_particleSystems;

        public CParticleManager()
        {
            m_particleSystems = new List<CBaseParticleSystem>();
            m_iRainPosition = 0;
            m_iExplosionStart = 0;
            m_iExplosionEnd = 0;

            CEventManager<SunXNA.SStep>.AddListener(this);
        }

        public void Initialise( Game game, float minHeight )
        {
            m_iMinTerrainHeight = minHeight;
            r_gGame = game;
            DefaultInitialise();
        }

        private void DefaultInitialise()
        {
            AddRainSystem();
            AddExplosionSystems();

            // Do last
            LoadAllParticleSystemsContent();
        }

        public void LoadAllParticleSystemsContent()
        {
            for (int i = 0; i < m_particleSystems.Count(); ++i)
            {
                m_particleSystems[i].LoadContent();
            }
        }

        private void AddRainSystem()
        {
            CRainParticleSystem rain = new CRainParticleSystem(MAX_RAIN_PARTICLES);
            rain.Initialise(r_gGame, m_iMinTerrainHeight);
            rain.ToggleActive(); // Start rain active

            m_particleSystems.Add(rain);
            m_iRainPosition = m_particleSystems.Count() - 1;
        }

        private void AddExplosionSystems()
        {
            m_iExplosionStart = m_particleSystems.Count;
            
            for (int i = 0; i < MAX_EXPLOSION; ++i)
            {
                CExplosion splode = new CExplosion(MAX_EXPLOSION_PARTICLES);
                splode.Initialise(r_gGame, m_iMinTerrainHeight);
                m_particleSystems.Add(splode);

            }

            m_iExplosionEnd = m_particleSystems.Count;
        }

        public void DoUpdate(float elapsedTime)
        {
            for (int i = 0; i < m_particleSystems.Count(); ++i)
            {
                if (m_particleSystems[i].IsActive())
                    m_particleSystems[i].DoUpdate(elapsedTime);
            }
        }

        public void DoRender(Matrix projMatrix, Matrix viewMatrix)
        {
            for (int i = 0; i < m_particleSystems.Count(); ++i)
            {
                if( m_particleSystems[i].IsActive() )
                    m_particleSystems[i].DoRender( projMatrix, viewMatrix);
            }
        }

        void IEventListener<SunXNA.SStep>.Handle( SunXNA.SStep e )
        {
            this.DoUpdate( (float)e.gameTime.ElapsedGameTime.TotalSeconds );
        }

        public void ActivateExplosionSystem(Vector3 origin)
        {
            if (MAX_EXPLOSION == 0)
            {
                return;
            }

            bool searchSuccess = false;
            int search = m_iExplosionStart;

            while (!searchSuccess && (search < m_iExplosionEnd ))
            {
                if (!m_particleSystems[search].IsActive())
                {
                    m_particleSystems[search].ResetParticleOrigin(origin);
                    m_particleSystems[search].ToggleActive();

                    searchSuccess = true;
                }
                else
                    ++search;

            }
        }

    }
}
